package com.ruoyi.web.controller.utils;

import java.util.Calendar;

public class CardUtils {
    public static boolean checkCardNumber(String cardNumber){
        int cardType = getCardType(cardNumber);
        if (cardType < 7 || cardNumber.length() >= 15){
            if(cardVerify(cardNumber)){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

    public static boolean checkExpdate(String expdate){
        if(!expdate.matches("[0-9]{2}/[0-9]{2}")){
            return false;
        };
        String[] exSarr = expdate.split("/");
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR) % 100;
        int month = calendar.get(Calendar.MONTH)+1;
        int cardMonth = Integer.valueOf(exSarr[0]);
        int cardYear = Integer.valueOf(exSarr[1]);
        //年份小
        if(cardYear<year){
            return false;
        }else if(cardYear==year){
            //年份相同，月份小
            if(cardMonth<month){
                return false;
            }
        }
        return true;
    }

    public static boolean checkCvv(String cardNumber, String cvv){
        //必须全部数字
        if(!cvv.matches("[0-9]*")){
            return false;
        };

        //CVV长度>=3
        if(cvv.length()<3){
            return false;
        }
        //卡类型
        int cardType = getCardType(cardNumber);
        if(cardType==5){
            if(cvv.length()!=4){
                return false;
            }
        }else{
            if(cvv.length()!=3){
                return false;
            }
        }
        return true;
    }


    private static boolean cardVerify(String s) {
        String v = "0123456789";
        String w = "";
        char i,x;
        int k, m, c, a;
        double j;

        for (int ii = 0; ii < s.length(); ii++) {
            x = s.charAt(ii);

            if (v.indexOf(x, 0) != -1) {
                w += x;
            }
        }

        j = w.length() / 2.0;
        k = (int) Math.floor(j);
        m = (int) Math.ceil(j) - k;
        c = 0;

        for (int ii = 0; ii < k; ii++) {
            int start = ii * 2 + m;
            a = Integer.valueOf(w.substring(start,start+1)) * 2;
            c += a > 9 ? Math.floor(a / 10 + a % 10) : a;
        }

        for (int ii = 0; ii < k + m; ii++) {
            int start = ii * 2 + 1 - m;
            c += Integer.valueOf(w.substring(start,start+1)) * 1;
        }
        return c % 10 == 0;
    }


    /**
     * 获取卡类型
     * @param cardNumber
     * @return
     */
    private static int getCardType(String cardNumber) {
        String number = cardNumber.replace(" ", "");
        if (number.matches("4\\d{12}(\\d{3})?(\\d{3})?")) {
            return 1;
        } else if (number.matches("3[47]\\d{13}")) {
            return 5;
        } else if (number.matches("(5[1-5]\\d{4}|677189|222[1-9]\\d{2}|22[3-9]\\d{3}|2[3-6]\\d{4}|27[01]\\d{3}|2720\\d{2})\\d{10}")) {
            return 2;
        } else if (number.matches("(6011|65\\d{2}|64[4-9]\\d)\\d{12}|(62\\d{14})")) {
            return 6;
        } else if (number.matches("35(28|29|[3-8]\\d)\\d{12}")) {
            return 3;
        } else if (number.matches("3(0[0-5]|[68]\\d)\\d{11}")) {
            return 4;
        } else {
            return 7;
        }
    }
}
